<?xml version="1.0" encoding="UTF-8"?><d:tdl xmlns="http://www.w3.org/1999/xhtml" xmlns:b="http://www.backbase.com/2006/btl" xmlns:bb="http://www.backbase.com/2006/client"  xmlns:d="http://www.backbase.com/2006/tdl" >

	<d:namespace name="http://www.backbase.com/2006/btl">

		<d:uses element="positionElement dimensionElement containerElement" src="../visualElement/visualElement.xml"/>
		<d:uses behavior="drag" src="../dragAndDrop/dragAndDrop.xml"/>
		<d:uses element="iconElement" src="../iconElement/iconElement.xml"/>
		<d:uses element="labelImplementor" src="../label/label.xml"/>

		<d:element name="modalBase" extends="b:positionElement b:dimensionElement b:containerElement b:iconElement b:drag b:labelImplementor" abstract="true">
			

			

			

			<d:resource type="text/css"><![CDATA[
				.btl-modal {
					position: absolute;
				}
				.btl-modal-layer-default {
					background-color: #000;
					position: absolute;
					top: 0;
					left: 0;
					opacity: 0.4;
				}
				.btl-modal-layer-default iframe {
					display: none;
				}
				.btl-modal-open {
					display: block;
				}
				.btl-modal-closed {
					display: none;
				}
				.btl-modal-focus-start {
					text-decoration: none;
				}
				.btl-modal-focus-end,
				.btl-modal-focus-after-end,
				.btl-modal-focus-before-start {
					border-style: none;
					font-size: 0;
					padding: 0;
					margin: 0;
					width: 0;
					height: 0;
					overflow:hidden;
					background-color: transparent;
				}
				.btl-modal-focus-before-start {
					position: absolute;
					left: 0;
					top: 0;
					width: 1px;
				}
				/* fixes */
				.ie .btl-modal-focus-end,
				.webkit .btl-modal-focus-end,
				.ie .btl-modal-focus-after-end,
				.webkit .btl-modal-focus-after-end,
				.ie .btl-modal-focus-before-start,
				.webkit .btl-modal-focus-before-start {
					/* To avoid space that appears under the content, caused by the textareas */
					position: absolute;
				}
				.ie .btl-modal-layer-default {
					-ms-filter: "alpha(opacity=40)";
					filter: alpha(opacity=40);
				}
				.ie6 .btl-modal-layer-default iframe {
					width: 100%;
                    height: 100%;
                    filter: alpha(opacity=0);
                    display: inline;
				}
				.webkit .btl-modal-focus-end,
				.webkit .btl-modal-focus-after-end,
				.webkit .btl-modal-focus-before-start {
					width: 1px;
					height: 1px;
					outline:none;
				}
				.webkit .btl-modal-focus-end:focus,
				.webkit .btl-modal-focus-after-end:focus,
				.webkit .btl-modal-focus-before-start:focus {
					visibility: hidden;
				}
				.webkit .btl-modal-focus-start {
					outline: none;
				}
			]]></d:resource>
			<d:resource type="text/javascript"><![CDATA[btl.modalBase = {};

btl.modalBase.oCurrentModal = [];

btl.modalBase.modalCount = 0;

btl.modalBase.iMinZindex = 990;

btl.modalBase.focusFlowDirection = 'forward';

btl.modalBase.focusPrevDirection = 'forward';

btl.modalBase.scrollHandler = function btl_modalBase_scrollHandler(eEvent){
	clearTimeout(btl.modalBase.tWaiter);
	btl.modalBase.tWaiter = setTimeout(function(){btl.modalBase.fixPositions()}, 300);
}

btl.modalBase.fixPositions = function btl_modal_fixPositions() {
	if(btl.modalBase.oCurrentModal != null) {
		for(var i = 0; i < btl.modalBase.oCurrentModal.length; i++) {
			if(btl.modalBase.oCurrentModal[i]._center) {
				var oModal = btl.modalBase.oCurrentModal[i].viewNode;
				var oParentModal = btl.modalBase.oCurrentModal[i].viewNode.parentNode;
				bb.html.position(oModal, oParentModal, 'center');
			}
		}
	}
};

btl.modalBase.flashModal = function btl_modal_flashModal(iN, oModal) {
	oModal.getProperty('startFocusElement').focus();
	iN--;
	if(iN>=0) {
		if(iN%2)
			bb.html.replaceClass(oModal.viewNode, 'btl-modal-active', 'btl-modal-inactive');
		else
			bb.html.replaceClass(oModal.viewNode, 'btl-modal-inactive', 'btl-modal-active');

		setTimeout(function(){btl.modalBase.flashModal(iN, oModal)}, 100);

	} else {
		bb.html.removeClass(oModal.viewNode, 'btl-modal-inactive')
		bb.html.addClass(oModal.viewNode, 'btl-modal-active')
	}
};

btl.modalBase.setModalLayer = function btl_modal_setModalLayer(oModal){
	if(oModal._){
		var sXml = '<div class="btl-modal-layer-default"><iframe /></div>';
		var oLayer = bb.html.createElementFromString(sXml);
		oLayer.onmousedown = function(){ btl.modalBase.flashModal(5, oModal); };

		var oParentModal = oModal.viewNode.parentNode;

		var position = bb.html.getStyle(oParentModal, "position");
		if((oParentModal.nodeName.toLowerCase()!='body') && (position != "relative") && (position != "absolute") && (position != "fixed")) {
			oParentModal.style.position = "relative";
		}

		oModal._.__layer = oLayer;

		btl.modalBase.setModalLayerDimensions(oModal);

		oLayer.style.zIndex = oModal.viewNode.style.zIndex-1;

		oParentModal.insertBefore(oLayer, oModal.viewNode);
	}
};

btl.modalBase.removeModalLayer = function btl_modal_removeModalLayer(oModal){
	if(oModal._ && oModal._.__layer){
		// adding this additional guard for full safety
		oModal._.__layer.parentNode && oModal._.__layer.parentNode.removeChild(oModal._.__layer);
		oModal._.__layer.onmousedown = null;
		oModal._.__layer = null;
	}
};

btl.modalBase.setModalLayerDimensions = function btl_modal_setModalLayerDimensions(oModal) {
	// set dimension of overlay to 100%
	// prevents unnecessary scrollbars when decreasing window size
	oModal._.__layer.style.height = '100%';
	oModal._.__layer.style.width = '100%';

	var oParent = oModal.viewNode.parentNode;
	var iHeight, iWidth;

	if(oParent.nodeName.toLowerCase() == 'body') {
		if(!bb.browser.ie) {
			iHeight = Math.max(document.documentElement.scrollHeight, oParent.scrollHeight);
			iWidth = Math.max(document.documentElement.scrollWidth, oParent.scrollWidth);
		} else {
			iHeight = Math.max(document.body.clientHeight, oParent.scrollHeight);
			iWidth = Math.max(document.body.clientWidth, oParent.scrollWidth);
		}
	} else {
		iHeight = Math.max(oParent.scrollHeight,oParent.offsetHeight);
		iWidth = Math.max(oParent.scrollWidth,oParent.offsetWidth);
	}

	var applyDimensions = function() {
		oModal._.__layer.style.height = iHeight + 'px';
		oModal._.__layer.style.width = iWidth + 'px';
	}

	if(bb.browser.ie) {
		setTimeout(applyDimensions, 1);
	} else {
		applyDimensions();
	}
}

btl.modalBase.loopFocus = function btl_modal_loopFocus(oModal, focusElement) {
		if(btl.modalBase.focusFlowDirection=='forward') {
			if(focusElement.className == 'btl-modal-focus-end') {
				oModal.getProperty('startFocusElement').focus();
			}
			else if(focusElement.className == 'btl-modal-focus-after-end') {
				oModal.getProperty('startFocusElement').focus();
			}
		}
		else if(btl.modalBase.focusFlowDirection=='back') {
			if(focusElement.className == 'btl-modal-focus-start') {
				oModal.getProperty('endFocusElement').focus();
				if(bb.browser.ie)
					oModal.getProperty('startFocusElement').scrollIntoView();
			}
			else if(focusElement.className == 'btl-modal-focus-before-start') {
				oModal.getProperty('endFocusElement').focus();
				if(bb.browser.ie)
					oModal.getProperty('startFocusElement').scrollIntoView();
			}
		}
	btl.modalBase.focusPrevDirection = btl.modalBase.focusFlowDirection;
};
]]></d:resource>

			<d:attribute name="dragConstraint" default="/*"/>

			<d:attribute name="for" default="/*">
				
			</d:attribute>

			<d:attribute name="open" default="false">
				
				<d:changer type="text/javascript"><![CDATA[
					var str = btl.isTrueValue(name, value) ? 'open' : 'close';
					if (str == 'open')
						this._open();
					else
						this._close();
					bb.command.fireEvent(this, str, false, false);
				]]></d:changer>
			</d:attribute>

			<!-- Make sure we set true or false to the prop. center, so if a 'strange' value is set, it will be false -->
			<d:attribute name="center" default="true">
				
			</d:attribute>

			<d:property name="beforeStartFocusElement">
				
				<d:getter type="text/javascript"><![CDATA[
					if(!this._['_beforeStartFocusElement'])
						this._['_beforeStartFocusElement'] = this.viewNode.getElementsByTagName('textarea')[0];
					return this._['_beforeStartFocusElement'];
				]]></d:getter>
			</d:property>

			<d:property name="startFocusElement">
				
				<d:getter type="text/javascript"><![CDATA[
					if(!this._['_startFocusElement'])
						this._['_startFocusElement'] = this.viewNode.getElementsByTagName('a')[0];
					return this._['_startFocusElement'];
				]]></d:getter>
			</d:property>

			<d:property name="endFocusElement">
				
				<d:getter type="text/javascript"><![CDATA[
					if(!this._['_endFocusElement']) {
						var aElm = this.viewNode.getElementsByTagName('textarea');
						this._['_endFocusElement'] = aElm[aElm.length-2];
					}
					return this._['_endFocusElement'];
				]]></d:getter>
			</d:property>

			<d:property name="afterEndFocusElement">
				
				<d:getter type="text/javascript"><![CDATA[
					if(!this._['_afterEndFocusElement']) {
						var aElm = this.viewNode.getElementsByTagName('textarea');
						this._['_afterEndFocusElement'] = aElm[aElm.length-1];
					}
					return this._['_afterEndFocusElement'];
				]]></d:getter>
			</d:property>

			<d:property name="center">
				
				<d:getter type="text/javascript"><![CDATA[
					return btl.isTrueValue(name, this.getAttribute(name));
				]]></d:getter>
				<d:setter type="text/javascript"><![CDATA[
					if(value == true)
						this.removeAttribute('center');
					else
						this.setAttribute('center', 'true');
				]]></d:setter>
			</d:property>

			<d:property name="open">
				
				<d:getter type="text/javascript"><![CDATA[
					return btl.isTrueValue(name, this.getAttribute(name));
				]]></d:getter>
				<d:setter type="text/javascript"><![CDATA[
					if(value == true)
						this.setAttribute('open', 'true');
					else
						this.removeAttribute('open');
				]]></d:setter>
			</d:property>

			<d:property name="previousActiveElement">
				
			</d:property>

			<d:method name="open">
				
				<d:body type="text/javascript"><![CDATA[
					this.setAttribute('open', 'true');
				]]></d:body>
			</d:method>

			<d:method name="_open">
				
				<d:body type="text/javascript"><![CDATA[
					this.setProperty('previousActiveElement', bb.activeElement);
					var oParent = this.viewNode.parentNode;

					this.viewNode.style.visibility = 'hidden';

					btl.modalBase.modalCount++;
					btl.modalBase.oCurrentModal[btl.modalBase.oCurrentModal.length] = this;

					// z-index is minimum plus active model length
					this.viewNode.style.zIndex = btl.modalBase.iMinZindex + btl.modalBase.oCurrentModal.length;

					btl.modalBase.setModalLayer(this);
					bb.html.replaceClass(this.viewNode, 'btl-modal-closed', 'btl-modal-open')
					//place the modal
					if(this.getProperty('center')) {
						//Fix for bugs 7635 & 8019
						if((bb.browser.gecko || bb.browser.opera) && oParent == document.body) {
							bb.html.position(this.viewNode, bb.viewport, 'center');
						}
						else {
							bb.html.position(this.viewNode, oParent, 'center');
						}
					}

					// show the modal
					this.viewNode.style.visibility = 'inherit';

					this.getProperty('startFocusElement').focus();

					bb.document.addEventListener('scroll', btl.modalBase.scrollHandler, false );

					bb.ui.reflow(this); // load hidden elements
				]]></d:body>
			</d:method>

			<d:method name="close">
				
				<d:body type="text/javascript"><![CDATA[
					this.setAttribute('open', 'false');
				]]></d:body>
			</d:method>

			<d:method name="_close">
				
				<d:body type="text/javascript"><![CDATA[

					btl.modalBase.removeModalLayer(this);

					btl.modalBase.modalCount--;

					if(btl.modalBase.modalCount == 0){
						btl.modalBase.oCurrentModal.length = 0;
						bb.document.removeEventListener('scroll', btl.modalBase.scrollHandler, false );
					}

					bb.html.replaceClass(this.viewNode, 'btl-modal-open', 'btl-modal-closed')
					var oActive = this.getProperty('previousActiveElement');
					// NOTE: in IE you need to check the visibility of the element
					if(oActive && oActive._ && (!bb.browser.ie || oActive.viewNode.offsetHeight)) {
						if(oActive.instanceOf('http://www.backbase.com/2006/btl', 'focusableElement')) {
							oActive.focus();
						} else if(oActive.viewNode.focus) {
							oActive.viewNode.focus();
						}
					}
				]]></d:body>
			</d:method>

			<d:destructor type="text/javascript"><![CDATA[
				this.getProperty('endFocusElement').onfocus = null;
				this.getProperty('startFocusElement').onfocus = null;
				this.getProperty('afterEndFocusElement').onfocus = null;
				this.getProperty('beforeStartFocusElement').onfocus = null;
				if(this.getProperty('open'))
					this._close();
				if(this.viewNode && this.viewNode.parentNode) {
					this.viewNode.parentNode.removeChild(this.viewNode);
				}
			]]></d:destructor>

			<d:handler event="construct" type="text/javascript"><![CDATA[
				bb.ui.reflow.add(this);
			]]></d:handler>

			<d:handler event="keydown" type="text/javascript"><![CDATA[
				if (event.shiftKey && event.keyIdentifier == 'F4') {
					// closing the modal by removing the open attribute (default is open="false")
					this.removeAttribute('open');
					event.preventDefault();
				}
				if (event.keyIdentifier == 'U+0009') {
					if (event.shiftKey)
						btl.modalBase.focusFlowDirection = 'back';
					else
						btl.modalBase.focusFlowDirection = 'forward';
				}
			]]></d:handler>

			<d:handler event="DOMNodeInsertedIntoDocument" type="text/javascript"><![CDATA[
				//add handler to endFocusElement for the focus flow loop
				var callFocusHandler = function(oModal){return function(){btl.modalBase.loopFocus(oModal, this)}};
				this.setAttribute('dragBehavior', 'move');
				this.getProperty('endFocusElement').onfocus = callFocusHandler(this);
				this.getProperty('startFocusElement').onfocus = callFocusHandler(this);
				this.getProperty('afterEndFocusElement').onfocus = callFocusHandler(this);
				this.getProperty('beforeStartFocusElement').onfocus = callFocusHandler(this);

				//check if target for blocking is set
				var sXpath = this.getAttribute('for');
					if(sXpath!='') {
						//evaluate xpath
						var oElm = bb.evaluateSmart(sXpath, this, this);

						//check if oElm is array or single object
						if(oElm[0]) { oElm = oElm[0]; }

						var oDest = oElm.viewGate;

						// if it's a regular html element and not a controller, use the regular html element instead
						if(oElm.nodeType && !(oElm.viewNode)) oDest = oElm;

						bb.command.move(this.viewNode, oDest, 'lastChild');
					}

				if(this.getProperty('open'))
					this._open();
			]]></d:handler>

			<d:handler event="reflow" type="text/javascript"><![CDATA[
				if(this.getProperty('open'))
					btl.modalBase.setModalLayerDimensions(this);
			]]></d:handler>
		</d:element>
	</d:namespace>
</d:tdl>